package com.dm.core.parser;

import com.dm.constant.DmConstants;
import com.dm.core.DatabaseMeta;
import com.dm.core.RedisTask;
import com.dm.core.SqlParserTable;
import com.dm.database.SQLType;
import com.dm.util.CollectionUtils;
import com.dm.util.StringUtils;
import com.google.gson.GsonBuilder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.update.Update;

/**
 *
 * @author zy
 * update类型的sql解析器
 */
public class UpdateSqlParser extends SqlParserTemplate {

	@Override
	protected Statement convertParserType(Statement statement) {
		if(statement instanceof Update) {
			Update upStatement = (Update) statement;
			return upStatement;
		}
		return null;
	}

	@Override
	protected void parserParameters(Statement statement, Map<String, SqlParserTable> SqlParserTable) throws InterruptedException {
		Update upStatement = (Update) statement;
		List<Table> tables =  upStatement.getTables();
		if (CollectionUtils.isEmpty(tables)) {
			return;
		}
		String tableName = tables.get(0).getName().replace("`", "");
		String tableKey = DatabaseMeta.getDatabaseName().concat(DmConstants.COLON).concat(tableName);
		Expression expressionWhere = upStatement.getWhere();
		SqlParserTable sqlParserTable = SqlParserTable.get(tableKey);
		if (expressionWhere == null) {
			return ;
		}
		String redisKey = null;
		String pk = sqlParserTable.getPk();
		List<Map<String, String>> whereKVMap = getKeyValue(expressionWhere, new ArrayList<>(10));
		RedisTask redisTask = new RedisTask();
		ArrayList<Object>[] parameters = task.getParameters();
		List<Map<String, String>> updateKv = getUpdateKV(upStatement);
		Map<String, String> updateValues = new HashMap<>(32);
		if (CollectionUtils.isEmpty(parameters)) {
			//采用的拼接sql方式
			redisKey = whereKVMap.stream().filter(e -> e.get(pk) != null).map(e -> e.get(pk)).findFirst().get();
			updateKv.stream().forEach(e -> updateValues.putAll(e));
		} else {
			//采用预编译执行方式
			int updateParasSize = updateKv.size();
			int length = parameters.length;
			int whereParaSize = whereKVMap.size();
			for (int i = 0; i < length; i++) {
				int finalI = i;
				int i1 = i - updateParasSize;
				if (i1 >= 0) {
					Map<String, String> whereMap = whereKVMap.get(i1);
					String pkValue = whereMap.get(pk.toLowerCase());
					if (StringUtils.isNotBlank(pkValue)) {
						redisKey = String.valueOf(parameters[finalI].get(0));
					}
				} else {
					updateKv.get(i).entrySet().stream().forEach(e -> {
						updateValues.put(e.getKey(), String.valueOf(parameters[finalI].get(0)));
					});
				}
			}
		}
		redisTask.setKey(redisKey = tableKey.concat(DmConstants.COLON).concat(redisKey));
		pipeline.getBq().put(new RedisTask(redisKey, new GsonBuilder().disableHtmlEscaping().create().toJson(updateValues), SQLType.UPDATE));

	}

	public List<Map<String, String>> getUpdateKV(Update updateStatement) {
		List<Column> columns = updateStatement.getColumns();
		List<Expression> expressions = updateStatement.getExpressions();
		if (CollectionUtils.isEmpty(columns) || CollectionUtils.isEmpty(expressions)) {
			return null;
		}
		List<Map<String, String>> kvs = new ArrayList<>(32);
		int size = columns.size();
		for (int i = 0; i < size; i++) {
			int finalI = i;
			kvs.add(new HashMap<String, String>(){{
				put(columns.get(finalI).getColumnName(), expressions.get(finalI).toString());
			}});
		}
		return kvs;
	}
}
